package com.youkeyi.ddy.cloud.basic.pub.user.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.youkeyi.ddy.cloud.basic.pub.mapping.entity.SysMapping;
import com.youkeyi.ddy.cloud.basic.pub.mapping.param.BusinessDeleteParam;
import com.youkeyi.ddy.cloud.basic.pub.mapping.param.BusinessQueryParam;
import com.youkeyi.ddy.cloud.basic.pub.mapping.service.SysMappingService;
import com.youkeyi.ddy.cloud.basic.pub.position.entity.SysPosition;
import com.youkeyi.ddy.cloud.basic.pub.position.service.SysPositionService;
import com.youkeyi.ddy.cloud.basic.pub.user.entity.SysUser;
import com.youkeyi.ddy.cloud.basic.pub.user.service.SysUserService;
import com.youkeyi.ddy.cloud.common.api.basic.pub.position.dto.PublicPositionListItemCloudDto;
import com.youkeyi.ddy.cloud.common.api.basic.pub.user.PublicUserCloudService;
import com.youkeyi.ddy.cloud.common.api.basic.pub.user.dto.PublicUserListCloudDto;
import com.youkeyi.ddy.cloud.common.api.basic.pub.user.dto.PublicUserListItemCloudDto;
import com.youkeyi.ddy.cloud.common.api.basic.pub.user.param.*;
import com.youkeyi.ddy.cloud.common.constant.YoukeyiDdyCloudBasicPublicConstant;
import com.youkeyi.ddy.cloud.common.enums.ResponseCodeEnum;
import com.youkeyi.ddy.cloud.common.response.ResponseContent;
import com.youkeyi.ddy.cloud.common.utils.SecurityUtils;
import com.youkeyi.ddy.cloud.common.utils.SimpleUUidUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author xiawang.liu
 * @since 2024-02-19
 */
@Service
public class SysUserController implements PublicUserCloudService {
    @Value("${user.default.password:Abc_123}")
    private String DEFAULT_PASSWORD;

    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysMappingService sysMappingService;
    @Autowired
    private SysPositionService sysPositionService;

    @Override
    public PublicUserListCloudDto query(PublicUserQueryCloudParam param) {
        PublicUserListCloudDto dto = new PublicUserListCloudDto();
        if (null == param) {
            dto.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return dto;
        }

        if (CollectionUtils.isNotEmpty(param.getUserPrimaryKeys())) {
            param.getUserPrimaryKeys().removeAll(Collections.singleton(null));
        }
        if (CollectionUtils.isNotEmpty(param.getCorpKeys())) {
            param.getCorpKeys().removeAll(Collections.singleton(null));
        }
        if (CollectionUtils.isNotEmpty(param.getCodes())) {
            param.getCodes().removeAll(Collections.singleton(null));
        }
        if (CollectionUtils.isNotEmpty(param.getPhones())) {
            param.getPhones().removeAll(Collections.singleton(null));
        }
        if (CollectionUtils.isNotEmpty(param.getAccounts())) {
            param.getAccounts().removeAll(Collections.singleton(null));
        }
        if (CollectionUtils.isNotEmpty(param.getOpenIds())) {
            param.getOpenIds().removeAll(Collections.singleton(null));
        }
        if (CollectionUtils.isNotEmpty(param.getUnionIds())) {
            param.getUnionIds().removeAll(Collections.singleton(null));
        }

        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .in(CollectionUtils.isNotEmpty(param.getUserPrimaryKeys()), SysUser::getPrimaryKey, param.getUserPrimaryKeys())
                .in(CollectionUtils.isNotEmpty(param.getCorpKeys()), SysUser::getCorpKey, param.getCorpKeys())
                .in(CollectionUtils.isNotEmpty(param.getAccounts()), SysUser::getAccount, param.getAccounts())
                .in(CollectionUtils.isNotEmpty(param.getPhones()), SysUser::getPhone, param.getPhones())
                .in(CollectionUtils.isNotEmpty(param.getCodes()), SysUser::getCode, param.getCodes())
                .in(CollectionUtils.isNotEmpty(param.getOpenIds()), SysUser::getOpenId, param.getOpenIds())
                .in(CollectionUtils.isNotEmpty(param.getOpenIds()), SysUser::getOfficialOpenId, param.getOfficialOpenIds())
                .in(CollectionUtils.isNotEmpty(param.getUnionIds()), SysUser::getUnionId, param.getUnionIds())
                .like(StringUtils.isNotBlank(param.getNameFuzzy()), SysUser::getName, param.getNameFuzzy())
                .like(StringUtils.isNotBlank(param.getNickNameFuzzy()), SysUser::getNickName, param.getNickNameFuzzy())
                .like(StringUtils.isNotBlank(param.getPhoneFuzzy()), SysUser::getPhone, param.getPhoneFuzzy())
                .like(StringUtils.isNotBlank(param.getEmailFuzzy()), SysUser::getEmail, param.getEmailFuzzy())
                .like(StringUtils.isNotBlank(param.getAccountFuzzy()), SysUser::getAccount, param.getAccountFuzzy())
                .ne(SysUser::getIsDeleted, YoukeyiDdyCloudBasicPublicConstant.SYSTEM_YES_OR_NO_YES.value())
        ;

        Page<SysUser> page = new Page<>();
        if (null != param.getCurrentPage() && null != param.getPageSize()) {
            page.setCurrent(param.getCurrentPage());
            page.setSize(param.getPageSize());
        } else {
            page.setCurrent(1);
            page.setSize(99999999);
        }
        Page<SysUser> userList = sysUserService.page(page, wrapper);
        if (CollectionUtils.isNotEmpty(userList.getRecords())) {
            dto.setTotal(userList.getTotal());

            // 查询映射数据
            BusinessQueryParam queryMappingParam = new BusinessQueryParam();
            queryMappingParam.setMappingType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_TYPE_USER_POSITION.value());
            queryMappingParam.setKeyType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_KEY_TYPE_SOURCE.value());
            queryMappingParam.setKeys(userList.getRecords().stream().map(SysUser::getPrimaryKey).collect(Collectors.toList()));
            Map<String, SysPosition> positionMap = new HashMap<>();
            Map<String, List<String>> positionKeysMap = new HashMap<>();
            List<SysMapping> sysMappings = sysMappingService.businessQuery(queryMappingParam);
            if (CollectionUtils.isNotEmpty(sysMappings)) {
                List<String> targetKeys = new ArrayList<>();
                sysMappings.forEach(mapping -> {
                    if (!positionKeysMap.containsKey(mapping.getSourceKey())) {
                        positionKeysMap.put(mapping.getSourceKey(), new ArrayList<>());
                    }
                    positionKeysMap.get(mapping.getSourceKey()).add(mapping.getTargetKey());

                    targetKeys.add(mapping.getTargetKey());
                });

                if (param.getNeedPosition()) {
                    QueryWrapper<SysPosition> positionQueryWrapper = new QueryWrapper<>();
                    positionQueryWrapper.lambda()
                            .in(SysPosition::getPrimaryKey, targetKeys)
                    ;
                    List<SysPosition> positions = sysPositionService.list(positionQueryWrapper);
                    if (CollectionUtils.isNotEmpty(positions)) {
                        positionMap.putAll(positions.stream().collect(Collectors.toMap(SysPosition::getPrimaryKey, Function.identity())));
                    }
                }
            }

            List<PublicUserListItemCloudDto> items = new ArrayList<>();
            userList.getRecords().forEach(user -> {
                PublicUserListItemCloudDto item = new PublicUserListItemCloudDto();
                item.setUserPrimaryKey(user.getPrimaryKey());
                item.setCorpKey(user.getCorpKey());
                item.setCode(user.getCode());
                item.setName(user.getName());
                item.setNickName(user.getNickName());
                item.setPhone(user.getPhone());
                item.setEmail(user.getEmail());
                item.setAccount(user.getAccount());
                item.setIsRoot(user.getIsRoot());
                item.setPassWord(user.getPassWord());
                item.setAvatarUrl(user.getAvatarUrl());
                item.setOpenId(user.getOpenId());
                item.setUnionId(user.getUnionId());
                item.setOfficialOpenId(user.getOfficialOpenId());
                item.setRemark(user.getRemark());
                item.setIsDeleted(user.getIsDeleted());
                item.setIsDeletedName(YoukeyiDdyCloudBasicPublicConstant.SYSTEM_YES_OR_NO.getName(item.getIsDeleted()));
                item.setCreateTime(user.getCreateTime() != null ? user.getCreateTime().getTime() : null);
                item.setCreateUserKey(user.getCreateUserKey());
                item.setCreateUserName(user.getCreateUserName());
                item.setUpdateTime(user.getUpdateTime() != null ? user.getUpdateTime().getTime() : null);
                item.setUpdateUserKey(user.getUpdateUserKey());
                item.setUpdateUserName(user.getUpdateUserName());
                if (positionKeysMap.containsKey(user.getPrimaryKey())) {
                    item.setPositionKeys(positionKeysMap.get(user.getPrimaryKey()));

                    if (param.getNeedPosition()) {
                        if (CollectionUtils.isNotEmpty(item.getPositionKeys())) {
                            item.getPositionKeys().forEach(positionKey -> {
                                SysPosition position = positionMap.get(positionKey);

                                PublicPositionListItemCloudDto positionItem = new PublicPositionListItemCloudDto();
                                positionItem.setPositionPrimaryKey(position.getPrimaryKey());
                                positionItem.setCorpKey(position.getCorpKey());
                                positionItem.setCode(position.getCode());
                                positionItem.setName(position.getName());
                                positionItem.setOrganizationKey(position.getOrganizationKey());
                                positionItem.setDesc(position.getDesc());
                                positionItem.setIsDeleted(position.getIsDeleted());
                                positionItem.setCreateTime(position.getCreateTime() != null ? position.getCreateTime().getTime() : null);
                                positionItem.setCreateUserKey(position.getCreateUserKey());
                                positionItem.setCreateUserName(position.getCreateUserName());
                                positionItem.setUpdateTime(position.getUpdateTime() != null ? position.getUpdateTime().getTime() : null);
                                positionItem.setUpdateUserKey(position.getUpdateUserKey());
                                positionItem.setUpdateUserName(position.getUpdateUserName());
                                item.getPositions().add(positionItem);
                            });
                        }
                    }
                }
                items.add(item);
            });
            dto.setRows(items);
        }
        dto.setSuccessMessage(ResponseCodeEnum.SUCCESS.getMessage());
        return dto;
    }

    @Override
    public ResponseContent create(PublicUserCreateCloudParam param) {
        ResponseContent rc = new ResponseContent();
        if (null == param || StringUtils.isBlank(param.getCorpKey()) || StringUtils.isBlank(param.getPhone())
                || StringUtils.isBlank(param.getName())) {
            rc.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return rc;
        }
        SysUser user = new SysUser();
        user.setPrimaryKey(StringUtils.defaultIfEmpty(param.getUserPrimaryKey(), SimpleUUidUtils.getUuid()));
        user.setCorpKey(param.getCorpKey());
        user.setName(param.getName());
        user.setCode(StringUtils.isNotBlank(param.getCode()) ? param.getCode() : String.format("USER-%s", System.currentTimeMillis()));
        user.setNickName(StringUtils.defaultIfEmpty(param.getNickName(), param.getName()));
        user.setPhone(param.getPhone());
        user.setEmail(param.getEmail());
        user.setAccount(param.getPhone());
        user.setIsRoot(param.getIsRoot());
        user.setPassWord(getEncryptPassword(user.getPrimaryKey(), param.getPassWord()));
        user.setAvatarUrl(param.getAvatarUrl());
        user.setOpenId(param.getOpenId());
        user.setUnionId(param.getUnionId());
        user.setOfficialOpenId(param.getOfficialOpenId());
        user.setRemark(param.getRemark());
        user.setIsDeleted(YoukeyiDdyCloudBasicPublicConstant.SYSTEM_YES_OR_NO_NO.value());
        user.setCreateUserKey(param.getCreateUserKey());
        user.setCreateUserName(param.getCreateUserName());
        user.setCreateTime(new Date());
        boolean save = sysUserService.save(user);
        if (!save) {
            rc.setErrorMessage(ResponseCodeEnum.FAIL.getMessage());
            return rc;
        }

        // 岗位数据录入
        if (CollectionUtils.isNotEmpty(param.getPositionKeys())) {
            List<SysMapping> serverCreateParams = new ArrayList<>();
            param.getPositionKeys().forEach(positionPrimaryKey -> {
                SysMapping serverMapping = new SysMapping();
                serverMapping.setPrimaryKey(SimpleUUidUtils.getUuid());
                serverMapping.setMappingType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_TYPE_USER_POSITION.value());
                serverMapping.setSourceKey(user.getPrimaryKey());
                serverMapping.setTargetKey(positionPrimaryKey);
                serverMapping.setCreateUserKey(param.getCreateUserKey());
                serverMapping.setCreateUserName(param.getCreateUserName());
                serverCreateParams.add(serverMapping);
            });
            sysMappingService.businessCreate(serverCreateParams);
        }

        rc.setSuccessMessage(ResponseCodeEnum.SUCCESS.getMessage());
        rc.setKey(user.getPrimaryKey());
        return rc;
    }

    @Override
    public ResponseContent update(PublicUserUpdateCloudParam param) {
        ResponseContent rc = new ResponseContent();
        if (null == param || StringUtils.isBlank(param.getUserPrimaryKey())) {
            rc.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return rc;
        }

        if (StringUtils.isNotBlank(param.getAccount()) || StringUtils.isNotBlank(param.getPhone())) {
            QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda()
                    .ne(SysUser::getPrimaryKey, param.getUserPrimaryKey())
                    .eq(StringUtils.isNotBlank(param.getPhone()), SysUser::getPhone, param.getPhone())
                    .eq(StringUtils.isNotBlank(param.getAccount()), SysUser::getAccount, param.getAccount())
                    .ne(SysUser::getIsDeleted, YoukeyiDdyCloudBasicPublicConstant.SYSTEM_YES_OR_NO_YES.value())
            ;
            SysUser user = sysUserService.getOne(queryWrapper);
            if (null != user) {
                rc.setErrorMessage(ResponseCodeEnum.UAS_UPDATE_USER_ACCOUNT_PHONE_FAIL.getMessage());
                return rc;
            }
        }

        UpdateWrapper<SysUser> wrapper = new UpdateWrapper<>();
        wrapper.lambda()
                .eq(SysUser::getPrimaryKey, param.getUserPrimaryKey());
        SysUser user = new SysUser();
        user.setCorpKey(param.getCorpKey());
        user.setCode(param.getCode());
        user.setName(param.getName());
        user.setNickName(param.getNickName());
        user.setPhone(param.getPhone());
        user.setEmail(param.getEmail());
        user.setAccount(param.getAccount());
        user.setIsRoot(param.getIsRoot());
        user.setAvatarUrl(param.getAvatarUrl());
        user.setOpenId(param.getOpenId());
        user.setUnionId(param.getUnionId());
        user.setOfficialOpenId(param.getOfficialOpenId());
        user.setRemark(param.getRemark());
        user.setUpdateUserKey(param.getUpdateUserKey());
        user.setUpdateUserName(param.getUpdateUserName());
        user.setUpdateTime(new Date());
        boolean save = sysUserService.update(user, wrapper);
        rc.setSuccessMessage(ResponseCodeEnum.SUCCESS.getMessage());
        if (!save) {
            rc.setErrorMessage(ResponseCodeEnum.FAIL.getMessage());
            return rc;
        }

        if (param.getUpdatePosition() != null && param.getUpdatePosition()) {
            // 删除映射数据
            BusinessDeleteParam deleteMappingParam = new BusinessDeleteParam();
            deleteMappingParam.setMappingType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_TYPE_USER_POSITION.value());
            deleteMappingParam.setKeyType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_KEY_TYPE_SOURCE.value());
            deleteMappingParam.setKeys(Collections.singletonList(param.getUserPrimaryKey()));
            sysMappingService.businessDelete(deleteMappingParam);
            // 重新加入映射数据
            if (CollectionUtils.isNotEmpty(param.getPositionKeys())) {
                List<SysMapping> serverCreateParams = new ArrayList<>();
                param.getPositionKeys().forEach(positionPrimaryKey -> {
                    SysMapping serverMapping = new SysMapping();
                    serverMapping.setPrimaryKey(SimpleUUidUtils.getUuid());
                    serverMapping.setMappingType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_TYPE_USER_POSITION.value());
                    serverMapping.setSourceKey(param.getUserPrimaryKey());
                    serverMapping.setTargetKey(positionPrimaryKey);
                    serverMapping.setCreateUserKey(param.getUpdateUserKey());
                    serverMapping.setCreateUserName(param.getUpdateUserName());
                    serverCreateParams.add(serverMapping);
                });
                sysMappingService.businessCreate(serverCreateParams);
            }
        }
        return rc;
    }

    @Override
    public ResponseContent updatePassword(PublicUserUpdatePasswordCloudParam param) {
        ResponseContent rc = new ResponseContent();
        if (null == param || StringUtils.isBlank(param.getUserPrimaryKey())
                || StringUtils.isBlank(param.getPasswordNew()) || StringUtils.isBlank(param.getPasswordOld())) {
            rc.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return rc;
        }

        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(SysUser::getPrimaryKey, param.getUserPrimaryKey());
        SysUser user = sysUserService.getOne(wrapper);
        if (null == user) {
            rc.setErrorMessage(ResponseCodeEnum.FAIL.getMessage());
        } else {
            String oldPassword = getEncryptPassword(user.getPrimaryKey(), param.getPasswordOld());
            if (user.getPassWord().equals(oldPassword)) {
                String newPassword = getEncryptPassword(user.getPrimaryKey(), param.getPasswordNew());

                SysUser updateUser = new SysUser();
                updateUser.setId(user.getId());
                updateUser.setPassWord(newPassword);
                boolean updateSuccess = sysUserService.updateById(updateUser);
                if (updateSuccess) {
                    rc.setSuccessMessage(ResponseCodeEnum.SUCCESS.getMessage());
                } else {
                    rc.setErrorMessage(ResponseCodeEnum.FAIL.getMessage());
                }
            } else {
                // 旧密码不匹配
                rc.setErrorMessage(ResponseCodeEnum.OLD_PASSWORD_INVALID.getMessage());
            }
        }
        return rc;
    }
    private String getEncryptPassword(String userKey, String password) {
        if (StringUtils.isBlank(password)) {
            password = DEFAULT_PASSWORD;
        }
        if (StringUtils.isNotBlank(userKey)) {
            String mdStr = SecurityUtils.md5(password, userKey);
            if (StringUtils.isNotBlank(mdStr)) {
                return mdStr;
            }
        }
        return null;
    }

    @Override
    public ResponseContent delete(PublicUserDeleteCloudParam param) {
        ResponseContent rc = new ResponseContent();
        if (null == param || CollectionUtils.isEmpty(param.getUserPrimaryKeys())) {
            rc.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return rc;
        }
        UpdateWrapper<SysUser> wrapper = new UpdateWrapper<>();
        wrapper.lambda()
                .in(SysUser::getPrimaryKey, param.getUserPrimaryKeys());

        SysUser user = new SysUser();
        user.setIsDeleted(YoukeyiDdyCloudBasicPublicConstant.SYSTEM_YES_OR_NO_YES.value());
        user.setUpdateUserKey(param.getUpdateUserKey());
        user.setUpdateUserName(param.getUpdateUserName());
        user.setUpdateTime(new Date());
        boolean save = sysUserService.update(user, wrapper);
        rc.setSuccessMessage(ResponseCodeEnum.SUCCESS.getMessage());
        if (!save) {
            rc.setErrorMessage(ResponseCodeEnum.FAIL.getMessage());
        }

        // 删除映射数据
        BusinessDeleteParam deleteMappingParam = new BusinessDeleteParam();
        deleteMappingParam.setMappingType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_TYPE_USER_POSITION.value());
        deleteMappingParam.setKeyType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_KEY_TYPE_SOURCE.value());
        deleteMappingParam.setKeys(param.getUserPrimaryKeys());
        sysMappingService.businessDelete(deleteMappingParam);
        return rc;
    }

    @Override
    public ResponseContent updateAvatar(PublicUserUpdateCloudParam param) {
        ResponseContent rc = new ResponseContent();
        if (null == param || StringUtils.isBlank(param.getUserPrimaryKey()) || StringUtils.isBlank(param.getCorpKey())) {
            rc.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return rc;
        }

        UpdateWrapper<SysUser> wrapper = new UpdateWrapper<>();
        wrapper.lambda()
                .eq(SysUser::getCorpKey, param.getCorpKey())
                .eq(SysUser::getPrimaryKey, param.getUserPrimaryKey());

        SysUser user = new SysUser();
        user.setPrimaryKey(param.getUserPrimaryKey());
        user.setAvatarUrl(param.getAvatarUrl());
        user.setUpdateUserKey(param.getUpdateUserKey());
        user.setUpdateTime(new Date());
        user.setUpdateUserName(param.getUpdateUserName());
        boolean save = sysUserService.update(user, wrapper);
        rc.setSuccessMessage(ResponseCodeEnum.SUCCESS.getMessage());
        if (!save) {
            rc.setErrorMessage(ResponseCodeEnum.FAIL.getMessage());
        }
        return rc;
    }

    @Override
    public ResponseContent updateNickName(PublicUserUpdateCloudParam param) {
        ResponseContent rc = new ResponseContent();
        if (null == param || StringUtils.isBlank(param.getUserPrimaryKey()) || StringUtils.isBlank(param.getCorpKey())) {
            rc.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return rc;
        }

        UpdateWrapper<SysUser> wrapper = new UpdateWrapper<>();
        wrapper.lambda()
                .eq(SysUser::getCorpKey, param.getCorpKey())
                .eq(SysUser::getPrimaryKey, param.getUserPrimaryKey());

        SysUser user = new SysUser();
        user.setPrimaryKey(param.getUserPrimaryKey());
        user.setNickName(param.getNickName());
        user.setUpdateUserKey(param.getUpdateUserKey());
        user.setUpdateTime(new Date());
        user.setUpdateUserName(param.getUpdateUserName());
        boolean save = sysUserService.update(user, wrapper);
        rc.setSuccessMessage(ResponseCodeEnum.SUCCESS.getMessage());
        if (!save) {
            rc.setErrorMessage(ResponseCodeEnum.FAIL.getMessage());
        }
        return rc;
    }
}
